/* 
 * Enterprise Library Extensions - DI + ORM.
 * Copyright (C) 2006
 *
 * GNU General Public License
 *
 * This program is free software; you can redistribute 
 * it and/or modify it under the terms of the GNU General Public License 
 * as published by the Free Software Foundation; either version 2 of the 
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful, but 
 * WITHOUT ANY WARRANTY; without even the implied warranty of 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
 * See the GNU General Public License for more details.
 */
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing.Design;
using Microsoft.Practices.EnterpriseLibrary.Configuration.Design;
using Microsoft.Practices.EnterpriseLibrary.Configuration.Design.Validation;
using ELE.EnterpriseLibrary.Data.Configuration.Design.Properties;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using System.Configuration;
using System.Reflection;

namespace ELE.EnterpriseLibrary.Data.Configuration.Design
{

  [Image(typeof(ObjectBindingOverwriteNode))]
  [SelectedImage(typeof(ObjectBindingOverwriteNode))]
  public class ObjectBindingOverwriteNode : ConfigurationNode
  {
    private bool isIgnore;
    private string inName;
    private string nullableValue;
    private string outName;

    private ObjectBindingNode bindingNode;
    private EventHandler<ConfigurationNodeChangedEventArgs> bindingNodeRemovedHandler;

    public ObjectBindingOverwriteNode()
      : this(new PropertyBindingOverwriteData(Resource.DefaultObjectBindingName))
    {
        
    }

    public ObjectBindingOverwriteNode(PropertyBindingOverwriteData data)
      : base((data == null) ? Resource.DefaultObjectBindingName : data.Name)
    {
      if (data == null) { throw new ArgumentNullException("PropertyBindingOverwriteData"); }
      this.bindingNodeRemovedHandler = new EventHandler<ConfigurationNodeChangedEventArgs>(OnBindingNodeRemoved);
      isIgnore = data.Ignore;
      inName = data.InName;
      nullableValue = data.NullableValue;
      outName = data.OutName;
      
    }
    private string NonEmptyString(string val)
    {
      if (string.IsNullOrEmpty(val)) return null;
      return val;
    }
    [Browsable(false)]
    public PropertyBindingOverwriteData BindingOverwriteData
    {
      get
      {
        PropertyBindingOverwriteData data = new PropertyBindingOverwriteData(Name);
        data.InName = this.NonEmptyString(this.InName);
        data.NullableValue = this.NonEmptyString(this.NullableValue);
        data.OutName = this.NonEmptyString(this.OutName);
        data.Ignore = this.Ignore;

	      return data;
      }
    }

    [Required]
    [SRDescription("ObjectBindingReferenceDescription", typeof(Resource))]
    [Editor(typeof(ReferenceEditor), typeof(UITypeEditor))]
    [ReferenceType(typeof(ObjectBindingNode))]
    [SRCategory("CategoryGeneral", typeof(Resource))]
    public ObjectBindingNode Binding
    {
      get { return bindingNode; }
      set
      {
        bindingNode = LinkNodeHelper.CreateReference<ObjectBindingNode>(bindingNode,
                                                                    value,
                                                                    bindingNodeRemovedHandler,
                                                                    null);
        this.Name = bindingNode.Name;
      }
    }

    public bool Ignore
    {
      get { return isIgnore; }
      set { isIgnore = value; }
    }

    public string InName
    {
      get { return inName; }
      set { inName = value; }
    }

    public string NullableValue
    {
      get { return nullableValue; }
      set { nullableValue = value; }
    }

    public string OutName
    {
      get { return outName; }
      set { outName = value; }
    }

    protected override void Dispose(bool disposing)
    {
      try
      {
        if (disposing)
        {
          if (null != bindingNode)
          {
            bindingNode.Removed -= bindingNodeRemovedHandler;
          }
        }
      }
      finally
      {
        base.Dispose(disposing);
      }
    }

    private void OnBindingNodeRemoved(object sender, ConfigurationNodeChangedEventArgs e)
    {
      this.bindingNode = null;
    }
  }
}